using System;
using System.Windows.Forms;
using Microsoft.StylusInput;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Collections.Generic;

namespace Woz
{
    /// <summary>
    /// the eraser tool class for erasing entities from the canvas
    /// </summary>
    public class EraserTool : Woz.Tool
    {
        /// <summary>
        /// the eraser tool class for erasing entities from the canvas
        /// </summary>
        /// <param name="pCanvasControl">the canvas to erase entities from</param>
        public EraserTool(Control pCanvasControl)
            : base(pCanvasControl)
        {
            // get the size
            float size = Woz.StaticVariables.Instance.InitialEraserSize;

            // create eraser cursor
            Bitmap blackX = new Bitmap((int)size, (int)size);
            Bitmap redX = new Bitmap((int)size, (int)size);

            // convert the size
            PointF[] pts = new PointF[] { new PointF(10.0f, 0), new PointF(10.0f + size, 0) };
            Woz.InkSpaceConverter.Instance.ApplyTransformationToPixel(pts);
            size = (pts[1].X - pts[0].X);

            // create the curve points
            PointF[] curvepts = new PointF[8]
            { 
                new PointF(0, 0), 
                new PointF(size / 3.0f, size / 2.0f),
                new PointF(0, size),
                new PointF(size / 2.0f, (2.0f * size) / 3.0f),
                new PointF(size, size),
                new PointF((2.0f * size) / 3.0f, size / 2.0f),
                new PointF(size, 0),
                new PointF(size / 2.0f, size / 3.0f)
            };

            // draw the black x
            using (Graphics gfx = Woz.InkSpaceConverter.Instance.InitializeInkGraphics(Graphics.FromImage(blackX)))
            {
                gfx.FillClosedCurve(Brushes.Black, curvepts);
                gfx.DrawClosedCurve(Pens.White, curvepts);
            }

            // draw the red x
            using (Graphics gfx = Woz.InkSpaceConverter.Instance.InitializeInkGraphics(Graphics.FromImage(redX)))
            {
                gfx.FillClosedCurve(Brushes.Red, curvepts);
                gfx.DrawClosedCurve(Pens.White, curvepts);
            }
            
            // save the eraser and active eraser
            Woz.ResourceManager.Instance.AddCursor("eraser", blackX);
            Woz.ResourceManager.Instance.AddCursor("erasered", redX);

            this.mErasedList = new List<Woz.Entity>();

            // set up the valid modes
            this.mValidModes.Add(Woz.StaticVariables.Instance.DesignScreens);
            //this.mValidModes.Add(Woz.StaticVariables.Instance.RunScreens);
        }

        /// <summary>
        /// the name of the tool
        /// </summary>
        public override string Name
        {
            get
            {
                return "Eraser";
            }
        }

        /// <summary>
        /// returns the name of the icon file
        /// </summary>
        public override string IconFileName
        {
            get
            {
                return "icon_eraser.png";
            }
        }

        /// <summary>
        /// get the data intersect and the in air packets
        /// </summary>
        public override DataInterestMask DataInterest
        {
            get
            {
                return base.DataInterest;
            }
        }

        protected override void OnProcessSelection()
        {
            base.SetCurrentCursor(Woz.ResourceManager.Instance.Cursors["eraser"]);
        }

        protected override void OnProcessDeselection()
        {
            base.SetCurrentCursor(Woz.ResourceManager.Instance.Cursors["arrow"]);
        }

        /// <summary>
        /// reset the pen tool
        /// </summary>
        public override void Reset()
        {
        }

        protected override void OnStylusUp(Point pLocation)
        {
            if (this.mErasedList.Count > 0)
            {
                // remove entities
                Woz.Action action = Woz.ActionManager.Instance.CreateAction(typeof(Woz.EraseAction), this.mErasedList.ToArray());
                action.Execute();

                // clear the list
                this.mErasedList.Clear();
            }
        }

        protected override void OnPackets(Point[] pLocations)
        {
            Woz.Entity eraseEntity = Woz.ScreenManager.Instance.SelectedScreen.HitTest(pLocations[0]);
            if (null != eraseEntity)
            {
                this.mErasedList.Add(eraseEntity);
                Woz.ScreenManager.Instance.SelectedScreen.RemoveEntity(eraseEntity, true);
                base.InvalidateRect(eraseEntity.BoundingBox);
            }
            base.SetCurrentCursor(Woz.ResourceManager.Instance.Cursors["erasered"]);
        }

        protected override void OnInAirPackets(Point[] pLocations)
        {
            if (Woz.ScreenManager.Instance.SelectedScreen.HitTest(pLocations[0]) != null)
            {
                base.SetCurrentCursor(Woz.ResourceManager.Instance.Cursors["erasered"]);
            }
            else
            {
                base.SetCurrentCursor(Woz.ResourceManager.Instance.Cursors["eraser"]);
            }
        }

        public override void Draw(Graphics pGraphics)
        {
        }

        private List<Woz.Entity> mErasedList;
    }
}
